﻿package com.dg.gaming.api.common.util 
{
	import flash.geom.ColorTransform;
	
	
	/**
	 * ...
	 * @author 
	 */
	public class Color 
	{
    
		/**
		 * The color white.  In the default sRGB space.
		 */
		public static const white:Color= new Color(255, 255, 255);

		/**
		 * The color white.  In the default sRGB space.
		 */
		public static const WHITE:Color= white;

		/**
		 * The color light gray.  In the default sRGB space.
		 */
		public static const lightGray:Color= new Color(192, 192, 192);

		/**
		 * The color light gray.  In the default sRGB space.
		 */
		public static const LIGHT_GRAY:Color= lightGray;

		/**
		 * The color gray.  In the default sRGB space.
		 */
		public static const gray:Color= new Color(128, 128, 128);

		/**
		 * The color gray.  In the default sRGB space.
		 */
		public static const GRAY:Color= gray;

		/**
		 * The color dark gray.  In the default sRGB space.
		 */
		public static const darkGray:Color= new Color(64, 64, 64);

		/**
		 * The color dark gray.  In the default sRGB space.
		 */
		public static const DARK_GRAY:Color= darkGray;

		/**
		 * The color black.  In the default sRGB space.
		 */
		public static const black:Color= new Color(0, 0, 0);
		
		/**
		 * The color black.  In the default sRGB space.
		 */
		public static const BLACK:Color= black;
		
		/**
		 * The color red.  In the default sRGB space.
		 */
		public static const red:Color= new Color(255, 0, 0);

		/**
		 * The color red.  In the default sRGB space.
		 */
		public static const RED:Color= red;

		/**
		 * The color pink.  In the default sRGB space.
		 */
		public static const pink:Color= new Color(255, 175, 175);

		/**
		 * The color pink.  In the default sRGB space.
		 */
		public static const PINK:Color= pink;

		/**
		 * The color orange.  In the default sRGB space.
		 */
		public static const orange:Color= new Color(255, 200, 0);

		/**
		 * The color orange.  In the default sRGB space.
		 */
		public static const ORANGE:Color= orange;

		/**
		 * The color yellow.  In the default sRGB space.
		 */
		public static const yellow:Color= new Color(255, 255, 0);

		/**
		 * The color yellow.  In the default sRGB space.
		 */
		public static const YELLOW:Color= yellow;

		/**
		 * The color green.  In the default sRGB space.
		 */
		public static const green:Color= new Color(0, 255, 0);

		/**
		 * The color green.  In the default sRGB space.
		 */
		public static const GREEN:Color= green;

		/**
		 * The color magenta.  In the default sRGB space.
		 */
		public static const magenta:Color= new Color(255, 0, 255);

		/**
		 * The color magenta.  In the default sRGB space.
		 */
		public static const MAGENTA:Color= magenta;

		/**
		 * The color cyan.  In the default sRGB space.
		 */
		public static const cyan:Color= new Color(0, 255, 255);

		/**
		 * The color cyan.  In the default sRGB space.
		 */
		public static const CYAN:Color= cyan;

		/**
		 * The color blue.  In the default sRGB space.
		 */
		public static const blue:Color= new Color(0, 0, 255);

		/**
		 * The color blue.  In the default sRGB space.
		 */
		public static const BLUE:Color= blue;

		/**
		 * Private data.
		 */
		private var pData:Number;

		/**
		 * The color value.
		 * @serial
		 * @see #getRGB
		 */
		private var value:int;

		/**
		 * The color value in the default sRGB <code>ColorSpace</code> as
		 * <code>float</code> components (no alpha).
		 * If <code>null</code> after object construction, this must be an
		 * sRGB color constructed with 8-bit precision, so compute from the
		 * <code>int</code> color value. 
		 * @serial
		 * @see #getRGBColorComponents
		 * @see #getRGBComponents
		 */
		private var frgbvalue:Array = null;

		/**
		 * The color value in the native <code>ColorSpace</code> as
		 * <code>float</code> components (no alpha).
		 * If <code>null</code> after object construction, this must be an
		 * sRGB color constructed with 8-bit precision, so compute from the
		 * <code>int</code> color value. 
		 * @serial
		 * @see #getRGBColorComponents
		 * @see #getRGBComponents  
		 */
		private var fvalue:Array  = null;

		/**
		 * The alpha value as a <code>float</code> component.
		 * If <code>frgbvalue</code> is <code>null</code>, this is not valid
		 * data, so compute from the <code>int</code> color value.
		 * @serial
		 * @see #getRGBComponents
		 * @see #getComponents
		 */
		private var falpha:Number= 0.0;





		/**
		 * Checks the color integer components supplied for validity.
		 * Throws an {@link IllegalArgumentException} if the value is out of
		 * range.
		 * @param r the Red component
		 * @param g the Green component
		 * @param b the Blue component
		 **/
		private static function testColorValueRange(r:int, g:int, b:int, a:int):void {
			var rangeError:Boolean= false;
		var badComponentString:String= "";
		
		if ( a < 0|| a > 255) {
			rangeError = true;
			badComponentString = badComponentString + " Alpha";
		}
			if ( r < 0|| r > 255) {
			rangeError = true;
			badComponentString = badComponentString + " Red";
		}
		if ( g < 0|| g > 255) {
			rangeError = true;
			badComponentString = badComponentString + " Green";
		}
		if ( b < 0|| b > 255) {
			rangeError = true;
			badComponentString = badComponentString + " Blue";
		}
		if ( rangeError == true ) {
		throw new Exception("Color parameter outside of expected range:"
						   + badComponentString);
		}
		}
		
		private function combineRGB(red:Number,green:Number,blue:Number):Number {
	
			var RGB:Number;
			
			if(red>255){red=255;}
			
			if(green>255){green=255;}
			
			if(blue>255){blue=255;}
			
			 
			
			if(red<0){red=0;}
			
			if(green<0){green=0;}
			
			if(blue<0){blue=0;}
			
			 
			
			RGB=(red<<16) | (green<<8) | blue;
			
			 
			
			return RGB;
	
		}
		/**
		 * Creates an sRGB color with the specified red, green, blue, and alpha
		 * values in the range (0 - 255).
		 *
		 * @throws IllegalArgumentException if <code>r</code>, <code>g</code>,
		 *        <code>b</code> or <code>a</code> are outside of the range
		 *        0 to 255, inclusive
		 * @param r the red component
		 * @param g the green component
		 * @param b the blue component
		 * @param a the alpha component
		 * @see #getRed
		 * @see #getGreen
		 * @see #getBlue
		 * @see #getAlpha
		 * @see #getRGB
		 */
		public function Color(r:int, g:int, b:int, a:int=255) {
			var ct:ColorTransform =new ColorTransform(r,g,b,a);
			value = combineRGB(r,g,b);
//			value = ((a & 0xFF) << 24) |
//					((r & 0xFF) << 16) |
//					((g & 0xFF) << 8)  |
//					((b & 0xFF) << 0);
		//testColorValueRange(r,g,b,a);
		}





		/**
		 * Returns the red component in the range 0-255 in the default sRGB
		 * space.
		 * @return the red component.
		 * @see #getRGB
		 */
		public function getRed():int {
		return (getRGB() >> 16) & 0xFF;
		}

		/**
		 * Returns the green component in the range 0-255 in the default sRGB
		 * space.
		 * @return the green component.
		 * @see #getRGB
		 */
		public function getGreen():int {
		return (getRGB() >> 8) & 0xFF;
		}

		/**
		 * Returns the blue component in the range 0-255 in the default sRGB
		 * space.
		 * @return the blue component.
		 * @see #getRGB
		 */
		public function getBlue():int {
		return (getRGB() >> 0) & 0xFF;
		}

		/**
		 * Returns the alpha component in the range 0-255.
		 * @return the alpha component.
		 * @see #getRGB
		 */
		public function getAlpha():int {
			return (getRGB() >> 24) & 0x0;
		}

		/**
		 * Returns the RGB value representing the color in the default sRGB
		 * {@link ColorModel}.
		 * (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are
		 * blue).
		 * @return the RGB value of the color in the default sRGB
		 *         <code>ColorModel</code>.
		 * @see java.awt.image.ColorModel#getRGBdefault
		 * @see #getRed
		 * @see #getGreen
		 * @see #getBlue
		 * @since JDK1.0
		 */
		public function getRGB():int {
				return value;
		}

		private static const FACTOR:Number= 0.7;

		/**
		 * Creates a new <code>Color</code> that is a brighter version of this
		 * <code>Color</code>.
		 * <p>
		 * This method applies an arbitrary scale factor to each of the three RGB 
		 * components of this <code>Color</code> to create a brighter version
		 * of this <code>Color</code>. Although <code>brighter</code> and
		 * <code>darker</code> are inverse operations, the results of a
		 * series of invocations of these two methods might be inconsistent
		 * because of rounding errors. 
		 * @return     a new <code>Color</code> object that is  
		 *                 a brighter version of this <code>Color</code>.
		 * @see        java.awt.Color#darker
		 * @since      JDK1.0
		 */
		public function brighter():Color {
			var r:int= getRed();
			var g:int= getGreen();
			var b:int= getBlue();

			/* From 2D group:
			 * 1. black.brighter() should return grey
			 * 2. applying brighter to blue will always return blue, brighter
			 * 3. non pure color (non zero rgb) will eventually return white
			 */
			var i:int= int((1.0/(1.0-FACTOR)));
			if ( r == 0&& g == 0&& b == 0) {
			   return new Color(i, i, i);
			}
			if ( r > 0&& r < i ) r = i;
			if ( g > 0&& g < i ) g = i;
			if ( b > 0&& b < i ) b = i;

			return new Color(Math.min(int((r/FACTOR)), 255),
							 Math.min(int((g/FACTOR)), 255),
							 Math.min(int((b/FACTOR)), 255));
		}

		/**
		 * Creates a new <code>Color</code> that is a darker version of this
		 * <code>Color</code>.
		 * <p>
		 * This method applies an arbitrary scale factor to each of the three RGB 
		 * components of this <code>Color</code> to create a darker version of
		 * this <code>Color</code>.  Although <code>brighter</code> and
		 * <code>darker</code> are inverse operations, the results of a series 
		 * of invocations of these two methods might be inconsistent because
		 * of rounding errors. 
		 * @return  a new <code>Color</code> object that is 
		 *                    a darker version of this <code>Color</code>.
		 * @see        java.awt.Color#brighter
		 * @since      JDK1.0
		 */
		public function darker():Color {
		return new Color(Math.max(int((getRed()  *FACTOR)), 0), 
				 Math.max(int((getGreen()*FACTOR)), 0),
				 Math.max(int((getBlue() *FACTOR)), 0));
		}

		/**
		 * Computes the hash code for this <code>Color</code>.
		 * @return     a hash code value for this object.
		 * @since      JDK1.0
		 */
		public function hashCode():int {
		return value;
		}

		/**
		 * Determines whether another object is equal to this 
		 * <code>Color</code>.
		 * <p>
		 * The result is <code>true</code> if and only if the argument is not 
		 * <code>null</code> and is a <code>Color</code> object that has the same 
		 * red, green, blue, and alpha values as this object. 
		 * @param       obj   the object to test for equality with this
		 *				<code>Color</code>
		 * @return      <code>true</code> if the objects are the same; 
		 *                             <code>false</code> otherwise.
		 * @since   JDK1.0
		 */
		public function equals(obj:Object):Boolean {
			return obj is Color && (Color(obj)).value == this.value;
		}

		/**
		 * Returns a string representation of this <code>Color</code>. This
		 * method is intended to be used only for debugging purposes.  The 
		 * content and format of the returned string might vary between 
		 * implementations. The returned string might be empty but cannot 
		 * be <code>null</code>.
		 * 
		 * @return  a string representation of this <code>Color</code>.
		 */
		public function toString():String {
			return "Color" + "[r=" + getRed() + ",g=" + getGreen() + ",b=" + getBlue() + "]";
		}

		
	}
	
}